package com.yy.weixinpay.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayConstants;
import com.alipay.api.internal.util.AlipaySignature;
import com.yy.weixinpay.entity.OrderInfo;
import com.yy.weixinpay.service.AliPayService;
import com.yy.weixinpay.service.OrderInfoService;
import com.yy.weixinpay.vo.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Map;

@RestController
@Api(tags = "支付宝支付相关接口")
@RequestMapping("/api/ali-pay")
@CrossOrigin
@Slf4j
public class AliPayController {
    @Autowired
    private AliPayService aliPayService;
    @Autowired
    private Environment config;
    @Autowired
    private OrderInfoService orderInfoService;

    /**
     * 调用支付接口
     * @param productId
     * @return
     */
    @ApiOperation("下单接口")
    @PostMapping("/trade/page/pay/{productId}")
    public R tradePagePay(@PathVariable Long productId){
        log.info("调用支付宝支付接口，id：{}",productId);
        String formString = aliPayService.tradeCreate(productId);

        return R.ok().data("formStr",formString);
    }

    @ApiOperation("支付通知")
    @PostMapping("/trade/notify")
    public String tradeNotify(@RequestParam Map<String,String> params){
        log.info("支付通知正在执行");
        log.info("通知参数：{}",params);

        //验签
        try {
            boolean result = AlipaySignature.rsaCheckV1(params, config.getProperty("alipay.alipay-public-key"), AlipayConstants.CHARSET_UTF8, AlipayConstants.SIGN_TYPE_RSA2);
            if (!result){
                log.info("通知验签失败");
                return "failure";
            }
            //验签成功
            String outTradeNo = params.get("out_trade_no");
            OrderInfo order = orderInfoService.getOrderByOrderNo(outTradeNo);
            //验证金额是否一致
            String totalAmount = params.get("total_amount");
            int totalAmountInt = new BigDecimal(totalAmount).multiply(new BigDecimal("100")).intValue();
            int totalFee = order.getTotalFee().intValue();
            if (totalAmountInt != totalFee){
                log.info("金额校验失败");
                return "failure";
            }
            String sellerId = params.get("seller_id");
            String sellerIdProperty = config.getProperty("alipay.seller-id");
            if (!sellerIdProperty.equals(sellerId)){
                log.info("商家pid校验失败");
                return "failure";
            }
            //验证app_id是否为商家本身
            String appId = params.get("app_id");
            String appidProperty = config.getProperty("alipay.app-id");
            if (!appId.equals(appidProperty)){
                log.info("appid校验失败");
                return "failure";
            }
            //获取通知状态
            String status = params.get("trade_status");
            if (!"TRADE_SUCCESS".equals(status)){
                log.info("支付未成功");
                return "failure";
            }
            log.info("支付宝支付成功");
            //更新订单状态和支付信息
            aliPayService.processOrder(params);
            return "success";
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 用户取消订单
     * @param orderNo
     * @return
     */
    @ApiOperation("用户取消订单")
    @PostMapping("/trade/close/{orderNo}")
    public R cancel(@PathVariable String orderNo){
        log.info("取消订单");
        aliPayService.cancelOrder(orderNo);
        return R.ok().setMessage("订单已取消");
    }

    @GetMapping("/trade/query/{orderNo}")
    @ApiOperation("查询订单")
    public R queryOrder(@PathVariable String orderNo){
        log.info("主动发起订单查询");
        String result = aliPayService.queryOrder(orderNo);
        return R.ok().setMessage("查询成功").data("result",result);
    }

    /**
     * 退款接口
     * @param orderNo
     * @param reason
     * @return
     */
    @PostMapping("/trade/refund/{orderNo}/{reason}")
    public R refunds(@PathVariable String orderNo,@PathVariable String reason){
        log.info("申请退款");
        aliPayService.refund(orderNo,reason);
        return R.ok();
    }

    /**
     * 退款查询
     * @param orderNo
     * @return
     */
    @ApiOperation("退款查询")
    @GetMapping("/trade/fastpay/refund/{orderNo}")
    public R queryFund(@PathVariable String orderNo){
        log.info("查询退款");
        String result = aliPayService.queryRefund(orderNo);
        return R.ok().setMessage("查询成功").data("result",result);
    }

    /**
     * 下载支付账单
     * @param billDate
     * @param type
     * @return
     */
    @ApiOperation("下载账单接口")
    @GetMapping("/bill/downloadurl/query/{billDate}/{type}")
    public R queryTradeBill(@PathVariable String billDate,@PathVariable String type){
        log.info("获取账单url");
        String downloadUrl = aliPayService.queryBill(billDate,type);
        return R.ok().setMessage("获取账单成功").data("downloadUrl",downloadUrl);
    }

}
